package com.ecoolex.ying.space.api.graphql;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.annotation.Description;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberAuthority;
import com.ecoolex.framework.modularize.api.service.storage.*;
import com.ecoolex.framework.web.api.graphql2.annotation.*;
import com.ecoolex.ying.space.entity.*;
import com.ecoolex.ying.space.enums.DesignerProjectType;
import com.ecoolex.ying.space.pojo.*;
import com.ecoolex.ying.space.ws.DesignerProjectService;
import com.ecoolex.ying.space.ws.PickGoodsService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@GraphQL2Module(type = GraphQL2Module.Type.User, description = "商品分类查询")
public class DesignerProjectGraphql {

    private static final UploadSource COVER_IMAGE_SOURCE = new UploadSource("DesignerProject", "CoverImage");
    private static final UploadLimit COVER_IMAGE_LIMIT = new UploadLimit(FileSize.MB.byteLength(5), MimeType.IMAGE.commons());

    private static final UploadSource CONTENT_IMAGE_SOURCE = new UploadSource("DesignerProjectItems", "ContentImage");
    private static final UploadLimit CONTENT_IMAGE_LIMIT = new UploadLimit(FileSize.MB.byteLength(5), MimeType.IMAGE.commons());

    @Reference
    private DesignerProjectService designerProjectService;

    @Reference
    private PickGoodsService pickGoodsService;

    @Autowired
    private StorageService storageService;

    @TypeField(type = DesignerProject.class, field = "coverImage", description = "封面图")
    public StorageInfo coverImage(@Source DesignerProject source) {
        return storageService.get(source.getCoverImage());
    }

    @TypeField(type = SimpleDesignerProjectDTO.class, field = "coverImage", description = "封面图")
    public StorageInfo coverImage(@Source SimpleDesignerProjectDTO source) {
        return storageService.get(source.getCoverImage());
    }

    @TypeField(type = DesignerProject.class, field = "attribute", description = "项目属性")
    public DesignerProjectAttribute attribute(@Source DesignerProject source) {
        return designerProjectService.getAttributeByProjectId(source.getProjectId());
    }

    @TypeField(type = DesignerProject.class, field = "share", description = "分享")
    public DesignerProjectShare share(@Source DesignerProject source) {
        return designerProjectService.getShareByProjectId(source.getProjectId());
    }

    @TypeField(type = DesignerProject.class, field = "planItemList", description = "方案条目集合")
    public List<DesignerProjectPlanItemsDTO> planItemList(@Source DesignerProject source) {
        if (DesignerProjectType.PLAN.notEqual(source.getType())) {
            return null;
        }
        return designerProjectService.queryItemsByProjectId(source.getProjectId())
                .stream()
                .map(item -> {
                    DesignerProjectPlanItemsDTO result = new DesignerProjectPlanItemsDTO();
                    result.setItemsId(item.getItemsId());
                    result.setContent(item.getContent());
                    result.setName(item.getName());
                    result.setPositionDescr(item.getPositionDescr());
                    if (Check.notNull(item.getImageResources())) {
                        result.setImages(JSON.parseArray(item.getImageResources(), String.class).stream().toArray(String[]::new));
                    }
                    return result;
                })
                .collect(Collectors.toList());
    }

    @TypeField(type = DesignerProjectPlanItemsDTO.class, field = "images", description = "方案图片集合")
    public StorageInfo[] images(@Source DesignerProjectPlanItemsDTO source) {
        if (Check.isNull(source.getImages())) {
            return null;
        }
        return Arrays.stream(source.getImages())
                .map(image -> storageService.get(image))
                .toArray(StorageInfo[]::new);
    }

    @TypeField(type = DesignerProjectPlanItemsDTO.class, field = "pickProducts", description = "优选商品产品列表")
    public List<DesignerProjectItemsPickProductDTO> pickProducts(@Source DesignerProjectPlanItemsDTO source) {
        return designerProjectService.queryItemsProductByItemsId(source.getItemsId())
                .stream()
                .map(itemsProduct -> {
                    DesignerProjectItemsPickProductDTO result = new DesignerProjectItemsPickProductDTO();
                    result.setPickProductId(itemsProduct.getPickProductId());
                    result.setNumber(itemsProduct.getNumber());
                    return result;
                }).collect(Collectors.toList());
    }

    @TypeField(type = DesignerProjectPlanItemsDTO.class, field = "pickProductList", description = "优选商品产品列表")
    public List<DesignerProjectItemsProduct> pickProductList(@Source DesignerProjectPlanItemsDTO source) {
        return designerProjectService.queryItemsProductByItemsId(source.getItemsId());
    }


    @TypeField(type = DesignerProject.class, field = "listingItemList", description = "清单条目集合")
    public List<DesignerProjectListingItemsDTO> listingItemList(@Source DesignerProject source) {
        if (DesignerProjectType.LISTING.notEqual(source.getType())) {
            return null;
        }
        return designerProjectService.queryItemsByProjectId(source.getProjectId())
                .stream()
                .map(item -> {
                    DesignerProjectListingItemsDTO result = new DesignerProjectListingItemsDTO();
                    result.setItemsId(item.getItemsId());
                    result.setPositionDescr(item.getPositionDescr());
                    return result;
                })
                .collect(Collectors.toList());
    }

    @TypeField(type = DesignerProjectListingItemsDTO.class, field = "pickProducts", description = "优选商品产品列表")
    public List<DesignerProjectItemsPickProductDTO> pickProducts(@Source DesignerProjectListingItemsDTO source) {
        return designerProjectService.queryItemsProductByItemsId(source.getItemsId())
                .stream()
                .map(itemsProduct -> {
                    DesignerProjectItemsPickProductDTO result = new DesignerProjectItemsPickProductDTO();
                    result.setPickProductId(itemsProduct.getPickProductId());
                    result.setNumber(itemsProduct.getNumber());
                    return result;
                }).collect(Collectors.toList());
    }

    @TypeField(type = DesignerProjectItemsPickProductDTO.class, field = "pickProduct", description = "优选商品产品")
    public PickGoodsProduct pickProduct(@Source DesignerProjectItemsPickProductDTO source) {
        return pickGoodsService.getProductById(source.getPickProductId());
    }

    @TypeField(type = DesignerProjectListingItemsDTO.class, field = "pickProductList", description = "优选商品产品列表")
    public List<DesignerProjectItemsProduct> pickProductList(@Source DesignerProjectListingItemsDTO source) {
        return designerProjectService.queryItemsProductByItemsId(source.getItemsId());
    }

    @TypeField(type = DesignerProjectItemsProduct.class, field = "pickProduct", description = "优选商品产品")
    public PickGoodsProduct pickProduct(@Source DesignerProjectItemsProduct source) {
        return pickGoodsService.getProductById(source.getPickProductId());
    }

    @TypeField(type = DesignerProjectItemsProduct.class, field = "custom", description = "自定义属性")
    public DesignerProjectItemsProductCustom custom(@Source DesignerProjectItemsProduct source) {
        return designerProjectService.getItemsProductCustomByItemsProductId(source.getItemsProductId());
    }

    @QueryField(field = "designerProject", description = "获取设计师项目详情")
    public DesignerProject designerProject(@NonNull Integer projectId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return designerProjectService.getProjectByUserIdAndId(user.userId(), projectId);
    }

    @QueryField(field = "designerProjectList", description = "查询设计师项目列表")
    public Pagination<DesignerProject> queryProjectByUserId(@NonNull QueryDesignerProjectByUserDTO query, @NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return designerProjectService.queryProjectByUserId(query, user.userId(), sorts, page);
    }



    @MutationField(field = "uploadDesignerProjectItemsContentImage", description = "上传设计师项目条目内容图片")
    public StorageInfo uploadDesignerProjectItemsContentImage(@NonNull Upload request, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.upload(request, CONTENT_IMAGE_SOURCE, CONTENT_IMAGE_LIMIT);
    }

    @MutationField(field = "uploadDesignerProjectCoverImage", description = "上传设计师项目封面图")
    public StorageInfo uploadDesignerProjectCoverImage(@NonNull Upload request, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.upload(request, COVER_IMAGE_SOURCE, COVER_IMAGE_LIMIT);
    }

    @MutationField(field = "addDesignerProject", description = "添加设计师项目")
    public DesignerProject createProject(@NonNull EditDesignerProjectDTO add, ConsumerMemberAuthority user) {
        user.assertLogin();
        return designerProjectService.createProject(user.userId(), add, user.userName());
    }

    @MutationField(field = "copyDesignerProject", description = "复制设计师项目")
    public DesignerProject copyDesignerProject(@NonNull Integer projectId, ConsumerMemberAuthority user) {
        user.assertLogin();
        DesignerProject project = designerProjectService.getProjectByUserIdAndId(user.userId(), projectId);
        Assert.isTrue(Check.notNull(project), ResultCode.VERIFY.build(1), "项目不存在");
        return designerProjectService.copyProject(user.userId(), project, user.userName());
    }

    @MutationField(field = "editDesignerProject", description = "修改设计师项目")
    public boolean updateProject(@NonNull Integer projectId, @NonNull EditDesignerProjectDTO edit, ConsumerMemberAuthority user) {
        user.assertLogin();
        designerProjectService.updateProject(user.userId(), projectId, edit, user.userName());
        return true;
    }

    @MutationField(field = "delDesignerProject", description = "删除设计师项目")
    public boolean deleteProject(@NonNull Integer projectId, ConsumerMemberAuthority user) {
        user.assertLogin();
        designerProjectService.deleteProject(user.userId(), projectId, user.userName());
        return true;
    }

    @MutationField(field = "editDesignerProjectAttribute", description = "修改设计师项目属性")
    public boolean updateAttribute(@NonNull Integer projectId, @NonNull EditDesignerProjectAttributeDTO edit, ConsumerMemberAuthority user) {
        user.assertLogin();
        designerProjectService.updateAttribute(user.userId(), projectId, edit, user.userName());
        return true;
    }

    @MutationField(field = "resetDesignerProjectShare", description = "重置设计师项目分享")
    public DesignerProjectShare resetShare(@NonNull Integer projectId, @NonNull @Description({"有效期天数; 0=永久; 其他有效参数: 1-30天"}) Integer expirydateDay, ConsumerMemberAuthority user) {
        user.assertLogin();
        return designerProjectService.resetShare(user.userId(), projectId, expirydateDay, user.userName());
    }

    @MutationField(field = "clearDesignerProjectShare", description = "清除设计师项目分享")
    public boolean clearShare(@NonNull Integer projectId, ConsumerMemberAuthority user) {
        user.assertLogin();
        designerProjectService.clearShare(user.userId(), projectId);
        return true;
    }

    @QueryField(field = "simpleDesignerProjectByShare", description = "简单的设计师分享项目的信息")
    public SimpleDesignerProjectDTO simpleDesignerProjectByShare(@NonNull String shareId) {
        DesignerProjectShare share = designerProjectService.getShareByShareId(shareId);
        if (Check.notNull(share)) {
            DesignerProject project = designerProjectService.getProjectById(share.getProjectId());
            if (Check.notNull(project)) {
                return new SimpleDesignerProjectDTO()
                        .setName(project.getName())
                        .setDescription(project.getDescription())
                        .setCoverImage(project.getCoverImage());
            }
        }
        return null;
    }

    @QueryField(field = "designerProjectByShare", description = "设计师分享的项目信息")
    public DesignerProject designerProjectByShare(@NonNull String shareId, @NonNull String password) {
        DesignerProjectShare share = designerProjectService.getShareByShareIdAndPassword(shareId, password);
        Assert.isTrue(Check.notNull(share), ResultCode.VERIFY.build(1), "密码错误");
        return designerProjectService.getProjectById(share.getProjectId());
    }

    @MutationField(field = "editDesignerProjectPlanItems", description = "编辑设计师项目方案条目")
    public List<DesignerProjectPlanItemsDTO> editDesignerProjectPlanItems(@NonNull Integer projectId, @NonNull List<EditDesignerProjectPlanItemsDTO> editList, ConsumerMemberAuthority user) {
        user.assertLogin();
        DesignerProject project = designerProjectService.getProjectByUserIdAndId(user.userId(), projectId);
        Assert.isTrue(Check.notNull(project), ResultCode.VERIFY.build(1), "项目不存在");
        Assert.isTrue(DesignerProjectType.PLAN.equal(project.getType()), ResultCode.VERIFY.build(2), "类型不一致");
        return designerProjectService.updatePlanItems(project, editList, user.userName());
    }

    @MutationField(field = "editDesignerProjectListingItems", description = "编辑设计师项目清单条目")
    public List<DesignerProjectListingItemsDTO> editDesignerProjectListingItems(@NonNull Integer projectId, List<EditDesignerProjectListingItemsDTO> editList, ConsumerMemberAuthority user) {
        user.assertLogin();
        DesignerProject project = designerProjectService.getProjectByUserIdAndId(user.userId(), projectId);
        Assert.isTrue(Check.notNull(project), ResultCode.VERIFY.build(1), "项目不存在");
        Assert.isTrue(DesignerProjectType.LISTING.equal(project.getType()), ResultCode.VERIFY.build(2), "类型不一致");
        return designerProjectService.updateListingItems(project, editList, user.userName());
    }

    @MutationField(field = "editDesignerProjectItemsProductCustom", description = "编辑设计师项目条目产品导出的自定义属性")
    public boolean editDesignerProjectItemsProductCustom(@NonNull Integer itemsProductId, EditDesignerProjectItemsProductCustomDTO edit, ConsumerMemberAuthority user) {
        user.assertLogin();
        designerProjectService.updateItemsProductCustom(user.userId(), itemsProductId, edit, user.userName());
        return true;
    }
}
